﻿using BarcodeStandard;
using log4net;
using SkiaSharp;
using StoreProject.BLL;
using StoreProject.BLL.SettingBLL;
using StoreProject.DAL;
using StoreProject.Entity;
using StoreProject.Forms.SettingForms;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Drawing.Printing;
using System.IO;
using System.Linq;
using System.Net.Http.Json;
using System.Reflection;
using System.Text;
using System.Text.Json.Serialization;
using System.Threading.Tasks;
using System.Windows.Forms;
using static System.Windows.Forms.DataFormats;
using static System.Windows.Forms.VisualStyles.VisualStyleElement;
using Type = BarcodeStandard.Type;
using StoreProject.OtherUtil;
using System.Net.Sockets;
using System.Runtime.Serialization.Formatters.Binary;
using StoreProject.Entity.OtherEntity;
using Org.BouncyCastle.Utilities;
using Newtonsoft.Json;

namespace StoreProject.Forms
{
    public partial class PrintOrderForm : Form
    {
        ILog _log = LogManager.GetLogger("PrintOrderForm");
        private PrintDocument pd = new PrintDocument();
        private OrderEntity orderEntity;
        private List<WorkingProcedureEntity> workingProcedureEntities;
        OrderBLL _orderBll = new OrderBLL();
        WorkingProcedureBLL workingProcedureBLL = new WorkingProcedureBLL();
        CustomerBLL customerBLL = new CustomerBLL();
        LineTypeBLL lineTypeBLL = new LineTypeBLL();
        ChangefulBLL changefulBLL = new ChangefulBLL();
        public PrintOrderForm()
        {
            InitializeComponent();
        }
        public PrintOrderForm(OrderEntity orderEntity, List<WorkingProcedureEntity> workingProcedureEntities)
        {
            this.orderEntity = orderEntity;
            this.workingProcedureEntities = workingProcedureEntities;
            InitializeComponent();
        }

        #region 打印相关
        IniConfig iniConfig = new IniConfig("printer_config.ini");
        public void Print()
        {
            try
            {
                CaptureScreen();
                if (IsExist())
                {
                    PrintByIniParam();
                }
                else
                {
                    SetPrinter();
                }
            }
            catch (Exception ex)
            {
                _log.Error(ex.ToString());
            }
        }

        /// <summary>
        /// 根据ini配置文件打印
        /// </summary>
        public void PrintByIniParam()
        {
            printDocument1.DefaultPageSettings.Landscape = Convert.ToBoolean(iniConfig.Read("Landscape", "OrderPrinter"));
            printDocument1.DefaultPageSettings.Margins.Right = Convert.ToInt32(iniConfig.Read("Right", "OrderPrinter"));
            printDocument1.DefaultPageSettings.Margins.Left = Convert.ToInt32(iniConfig.Read("Left", "OrderPrinter"));
            printDocument1.DefaultPageSettings.Margins.Top = Convert.ToInt32(iniConfig.Read("Top", "OrderPrinter"));
            printDocument1.DefaultPageSettings.Margins.Bottom = Convert.ToInt32(iniConfig.Read("Bottom", "OrderPrinter"));


            printDocument1.PrinterSettings.PrinterName = iniConfig.Read("PrinterName", "OrderPrinter");

            printDocument1.DefaultPageSettings.PaperSize = new System.Drawing.Printing.PaperSize(iniConfig.Read("PaperName", "OrderPrinter"), Convert.ToInt32(iniConfig.Read("Width", "OrderPrinter")), Convert.ToInt32(iniConfig.Read("Height", "OrderPrinter")));

            printDocument1.Print();
        }
        public bool IsExist()
        {
            var flag = iniConfig.KeyExists("Landscape", "OrderPrinter");
            if (!flag)
                return false;
            flag = iniConfig.KeyExists("PrinterName", "OrderPrinter");
            if (!flag)
                return false;
            flag = iniConfig.KeyExists("Top", "OrderPrinter");
            if (!flag)
                return false;
            flag = iniConfig.KeyExists("Bottom", "OrderPrinter");
            if (!flag)
                return false;
            flag = iniConfig.KeyExists("Left", "OrderPrinter");
            if (!flag)
                return false;
            flag = iniConfig.KeyExists("Right", "OrderPrinter");
            if (!flag)
                return false;
            flag = iniConfig.KeyExists("PaperName", "OrderPrinter");
            if (!flag)
                return false;
            flag = iniConfig.KeyExists("RawKind", "OrderPrinter");
            if (!flag)
                return false;
            flag = iniConfig.KeyExists("Width", "OrderPrinter");
            if (!flag)
                return false;
            flag = iniConfig.KeyExists("Height", "OrderPrinter");
            if (!flag)
                return false;
            return true;
        }

        /// <summary>
        /// 设置打印机参数保存到INI文件，并打印一次
        /// </summary>
        public void SetPrinter()
        {
            PrinterSettingEntity printerSettingEntity = new PrinterSettingEntity();
            PageSetting pageSetting = new PageSetting();
            PrinterSetting printerSetting = new PrinterSetting();
            //先把中变变量设置到控件中
            PageSetupDialog pageSetupDialog1 = new PageSetupDialog();
            pageSetupDialog1.Document = printDocument1;
            pageSetupDialog1.AllowMargins = true;
            pageSetupDialog1.AllowOrientation = true;
            pageSetupDialog1.AllowPaper = true;
            pageSetupDialog1.AllowPrinter = true;
            pageSetupDialog1.ShowHelp = true;
            if (pageSetupDialog1.ShowDialog() == DialogResult.OK)
            {
                printDocument1.DefaultPageSettings = pageSetupDialog1.PageSettings;
                pageSetting.Landscape = printDocument1.DefaultPageSettings.Landscape;

                pageSetting.PaperSize = new Entity.OtherEntity.PaperSize();
                pageSetting.PaperSize.PaperName = printDocument1.DefaultPageSettings.PaperSize.PaperName;
                pageSetting.PaperSize.RawKind = printDocument1.DefaultPageSettings.PaperSize.RawKind;
                pageSetting.PaperSize.Width = printDocument1.DefaultPageSettings.PaperSize.Width;
                pageSetting.PaperSize.Height = printDocument1.DefaultPageSettings.PaperSize.Height;
                pageSetting.PaperSize.Kind = (int)printDocument1.DefaultPageSettings.PaperSize.Kind;

                pageSetting.Margin = new Margin();
                pageSetting.Margin.Top = printDocument1.DefaultPageSettings.Margins.Top;
                pageSetting.Margin.Bottom = printDocument1.DefaultPageSettings.Margins.Bottom;
                pageSetting.Margin.Left = printDocument1.DefaultPageSettings.Margins.Left;
                pageSetting.Margin.Right = printDocument1.DefaultPageSettings.Margins.Right;
                //printDocument1.DefaultPageSettings.Margins;
                printerSettingEntity.pageSetting = pageSetting;
            }
            else
                return;

            PrintDialog print = new PrintDialog();
            print.Document = printDocument1;
            print.AllowCurrentPage = true;
            print.AllowPrintToFile = true;
            print.AllowSelection = true;
            print.AllowSomePages = true;
            print.ShowHelp = true;
            if (print.ShowDialog() == DialogResult.OK)
            {
                printDocument1.PrinterSettings = print.PrinterSettings;
                printerSetting.PrinterName = printDocument1.PrinterSettings.PrinterName;
                printerSettingEntity.printerSetting = printerSetting;
            }
            else
                return;
            iniConfig.Write("Landscape", printerSettingEntity.pageSetting.Landscape == true ? "True" : "False", "OrderPrinter");
            iniConfig.Write("Top", printerSettingEntity.pageSetting.Margin.Top.ToString(), "OrderPrinter");
            iniConfig.Write("Bottom", printerSettingEntity.pageSetting.Margin.Bottom.ToString(), "OrderPrinter");
            iniConfig.Write("Left", printerSettingEntity.pageSetting.Margin.Left.ToString(), "OrderPrinter");
            iniConfig.Write("Right", printerSettingEntity.pageSetting.Margin.Right.ToString(), "OrderPrinter");
            iniConfig.Write("PrinterName", printerSettingEntity.printerSetting.PrinterName, "OrderPrinter");

            iniConfig.Write("PaperName", printerSettingEntity.pageSetting.PaperSize.PaperName, "OrderPrinter");
            iniConfig.Write("RawKind", printerSettingEntity.pageSetting.PaperSize.RawKind.ToString(), "OrderPrinter");
            iniConfig.Write("Width", printerSettingEntity.pageSetting.PaperSize.Width.ToString(), "OrderPrinter");
            iniConfig.Write("Height", printerSettingEntity.pageSetting.PaperSize.Height.ToString(), "OrderPrinter");
            //打印的是中间变量
            printDocument1.Print();
        }
        private void btnPrint_Click(object sender, EventArgs e)
        {
            if (string.IsNullOrEmpty(this.cmbOrderId.Text))
            {
                MessageBox.Show("制令单号不得为空!", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }

            var isExist = _orderBll.GetListByWhere(this.cmbOrderId.Text).ToList();
            if (isExist == null || isExist.Count() < 1)
            {
                MessageBox.Show("制令单号不存在!", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }

            orderEntity = new OrderEntity();
            orderEntity.Id = isExist.ToList()[0].Id;
            orderEntity.CreateTime = isExist.ToList()[0].CreateTime;
            orderEntity.Operator = isExist.ToList()[0].Operator;
            orderEntity.OrderId = this.cmbOrderId.Text;
            orderEntity.Batch = this.txtBatch.Text;
            orderEntity.SemiFinishedProductName = this.txtSemiFinishedProductName.Text;
            orderEntity.PlanNums = Convert.ToInt32(numPlanNum.Value);
            orderEntity.FinishedProductName = this.txtFinishedProductName.Text;
            orderEntity.LineType = this.cmbLineType.Text;
            orderEntity.Customer = this.cmbCustomer.Text;
            orderEntity.RequestedDate = this.dateTimeRequestedDate.Value;
            orderEntity.UpdateTime = DateTime.Now;
            orderEntity.JuanNum = this.txtJuanNum.Text;
            orderEntity.DanZhong = this.txtDanZhong.Text;
            orderEntity.DomesticAndExportSales = this.cmbDomesticAndExportSales.Text;
            var item = cmbProcessFlow.SelectedItem as ProcessFlow;
            if (item != null)
                orderEntity.ProcessFlowId = item.Id;

            isExist[0].DanZhong = this.txtDanZhong.Text;
            isExist[0].SemiFinishedProductName = this.txtSemiFinishedProductName.Text;
            _orderBll.Update(isExist[0]);
            _log.Info(string.Format("打印后的制令单的基础数据为：{0}", JsonConvert.SerializeObject(isExist[0])));
            var newchangeEntity = changefulBLL.GetList().ToList();
            _log.Info(string.Format("打印后的批号为：{0}", newchangeEntity[0].BatchNo));
            workingProcedureEntities = workingProcedureBLL.GetListByStatus(orderEntity.ProcessFlowId).OrderBy(x => x.IndexNum).ToList();
            Print();
        }

        private void printDocument1_PrintPage(object sender, PrintPageEventArgs e)
        {
            e.Graphics.DrawImage(memoryImage, 0, 0);
            //Graphics gh = e.Graphics;
            //Pen p = new Pen(new SolidBrush(Color.Black));
            //for (int i = 0; i < 9; i++)
            //{
            //    gh.DrawLine(p, 5, 180 + i * 27, 550, 180 + i * 27);
            //    //gh.DrawLine(p, 5 + i * 30, 180, 5 + i * 30, 550);
            //}
            //for (int i = 0; i < 12; i++)
            //{
            //    if (i == 11)
            //    {
            //        gh.DrawLine(p, 550, 180, 550, 396);
            //    }
            //    else
            //        gh.DrawLine(p, 5 + i * 49, 180, 5 + i * 49, 396);
            //}
        }
        private Bitmap memoryImage;
        private void CaptureScreen()
        {
            var form1 = new TestPrintForm(orderEntity, workingProcedureEntities);
            var createControl = form1.GetType().GetMethod("CreateControl",
                            BindingFlags.Instance | BindingFlags.NonPublic);
            createControl.Invoke(form1, new object[] { true });

            var bm = new Bitmap(form1.Width, form1.Height);
            form1.DrawToBitmap(bm, new Rectangle(0, 0, bm.Width, bm.Height));
            //bm.Save(@"d:\bm.bmp");
            memoryImage = bm;
        }

        #endregion
        private void PrintOrderForm_Load(object sender, EventArgs e)
        {
            try
            {
                printDocument1.EndPrint += PrintDocument1_EndPrint;
                cmbProcessFlow.DisplayMember = "ProcessFlowName";
                cmbProcessFlow.ValueMember = "Id";
                cmbLineType.DisplayMember = "LineTypeName";
                cmbLineType.ValueMember = "LineTypeName";
                cmbCustomer.DisplayMember = "CustomerName";
                cmbCustomer.ValueMember = "CustomerName";

                var list = _orderBll.GetList().OrderByDescending(x => x.OrderId).Take(100).ToList().Select(x => x.OrderId).ToArray();
                this.cmbOrderId.Items.AddRange(list);
                InitData();
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
        }

        private void PrintDocument1_EndPrint(object sender, PrintEventArgs e)
        {
            MessageBox.Show("打印已完成!", "信息提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
        }

        public void InitData()
        {
            //工序数据源配置
            List<ProcessFlow> list = new List<ProcessFlow>();
            var groupList = workingProcedureBLL.GetListEx().GroupBy(x => x.ProcessFlowId);
            foreach (var group in groupList)
            {
                ProcessFlow processFlow = new ProcessFlow();
                processFlow.Id = group.Key;
                string temp = "";
                foreach (var item in group.ToList().OrderBy(x => x.IndexNum))
                {
                    temp += (item.IndexName + "+");
                }
                if (!string.IsNullOrEmpty(temp))
                    temp = temp.Remove(temp.Length - 1, 1);
                processFlow.ProcessFlowName = temp;
                list.Add(processFlow);

            }
            cmbProcessFlow.DataSource = list;

            //客户数据源配置
            var customer = customerBLL.GetList().ToList();
            cmbCustomer.DataSource = customer;

            //线型数据源配置
            var linetype = lineTypeBLL.GetList().ToList();
            cmbLineType.DataSource = linetype;
        }
        private void numPlanNum_KeyPress(object sender, KeyPressEventArgs e)
        {
            if (((int)e.KeyChar < 48 || (int)e.KeyChar > 57) && (int)e.KeyChar != 8 && (int)e.KeyChar != 46)
                e.Handled = true;
        }

        private void cmbOrderId_KeyDown_1(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Enter)
            {
                ChangeValue();
            }
        }

        private void cmbOrderId_SelectedValueChanged(object sender, EventArgs e)
        {
            ChangeValue();
        }

        public void ChangeValue()
        {
            if (!string.IsNullOrEmpty(cmbOrderId.Text))
            {
                var list = _orderBll.GetListByWhere(cmbOrderId.Text).ToList();
                if (list == null || list.Count < 1)
                {
                    MessageBox.Show("该制令单号不存在!", "警告", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                    return;
                }
                _log.Info(string.Format("打印前的制令单的基础数据为：{0}", JsonConvert.SerializeObject(list[0])));
                orderEntity = list[0];
                this.txtBatch.Text = orderEntity.Batch;
                this.txtFinishedProductName.Text = orderEntity.FinishedProductName;
                this.numPlanNum.Value = orderEntity.PlanNums;
                this.txtSemiFinishedProductName.Text = orderEntity.SemiFinishedProductName;
                this.cmbLineType.Text = orderEntity.LineType;
                this.cmbCustomer.Text = orderEntity.Customer;
                this.dateTimeRequestedDate.Value = orderEntity.RequestedDate;
                this.txtJuanNum.Text = orderEntity.JuanNum;
                this.txtDanZhong.Text = orderEntity.DanZhong;
                this.cmbDomesticAndExportSales.Text = this.orderEntity.DomesticAndExportSales;
                if (!string.IsNullOrEmpty(orderEntity.ProcessFlowId))
                {
                    var temp = workingProcedureBLL.GetListByStatus(orderEntity.ProcessFlowId).ToList()[0];
                    cmbProcessFlow.SelectedValue = temp.ProcessFlowId;
                }
            }
        }

        private void PrintOrderForm_FormClosing(object sender, FormClosingEventArgs e)
        {
            this.printDocument1.Dispose();
            this.printDocument1 = null;
        }
    }
}
